package com.example.widget_lib.widget.base;

import java.util.ArrayList;
import java.util.List;

import ohos.agp.animation.Animator;
import ohos.agp.animation.AnimatorValue;
import ohos.agp.components.AttrSet;
import ohos.agp.components.Component;
import ohos.agp.render.Canvas;
import ohos.agp.render.Paint;
import ohos.agp.utils.Color;
import ohos.agp.utils.Point;
import ohos.app.Context;
import ohos.eventhandler.EventHandler;
import ohos.eventhandler.EventRunner;

/**
 * 曲线控件抽象类
 *
 * @autor hongbing
 * @date 2018/12/18
 */
public abstract class BaseGradientView extends Component {

    private static final String TAG = "GradientLine";
    private static final boolean isDebug = true;
    protected int mView_W, mView_H; // view的宽高
    protected Mode mMode;
    protected boolean mIsAnim; // 是否使用动画
    protected int mAnimDuration = 320; // 动画时长
    protected float mPer;
    protected boolean mIsRunging;
    private List<Point> mPointList = null;
    private List<Point> mBezierPoints = null;
    /**
     * 开始图形动画
     */
    private AnimatorValue mAnimator;

    public BaseGradientView(Context context, AttrSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
        int ordinal = Mode.None.ordinal();
        mMode = Mode.values()[ordinal];
        init();
    }

    protected void init() {
        mPointList = new ArrayList<>(5);
        mBezierPoints = new ArrayList<>(5);
        setBindStateChangedListener(new BindStateChangedListener() {
            @Override
            public void onComponentBoundToWindow(Component component) {

            }

            @Override
            public void onComponentUnboundFromWindow(Component component) {
                cancelAnim();
            }
        });
    }

    public void setAnim(boolean isAnim) {
        mIsAnim = isAnim;
    }

    public void setAnim(boolean isAnim, int duration) {
        mIsAnim = isAnim;
        mAnimDuration = duration;
    }

    public void setAnimDuration(int duration) {
        mAnimDuration = duration;
    }

    protected void addPoint(float x, float y) {
        mPointList.add(new Point(x, y));
    }

    protected void clearPoints() {
        mPointList.clear();
    }

    protected void clearBezierPoints() {
        mBezierPoints.clear();
    }

    protected void clearPointsAll() {
        clearPoints();
        clearBezierPoints();
    }

    protected List<Point> getPoints() {
        return mPointList;
    }

    protected void updatePath(Canvas canvas, List<Point> points, Mode mode) {
        int size = points.size();
        if (size <= 0) {
            return;
        }
        if (size == 1) { // 开始连线
            mBezierPoints.add(new Point(points.get(0).getPointX(), points.get(0).getPointY()));
            drawBezierPoint(mBezierPoints, canvas, mode);

            // 测试数据
//            Paint paint = new Paint(Paint.ANTI_ALIAS_FLAG);
//            paint.setColor(Color.BLUE);
//            paint.setStrokeWidth(2);
//            canvas.drawCircle(points.get(0).x,points.get(0).y,4,paint);


            return;
        }
        List<Point> nextPoints = new ArrayList<>();

        int index = 1;
        int var7 = size - 1;
        if (index <= var7) {
            while (true) {
                double nextPointX = points.get(index - 1).getPointX() - (points.get(index - 1).getPointX() - points.get(index).getPointX()) * mPer;
                double nextPointY = points.get(index - 1).getPointY() - (points.get(index - 1).getPointY() - points.get(index).getPointY()) * mPer;
                nextPoints.add(new Point((float) nextPointX, (float)nextPointY));
                if (index == var7) {
                    break;
                }
                ++index;
            }
        }

        // 绘制下一层
        updatePath(canvas, nextPoints, mode);
    }

    /**
     * 动画绘制贝塞尔曲线
     *
     * @param bazierPoints
     * @param canvas
     * @param mode         图形模式
     */
    protected abstract void drawBezierPoint(List<Point> bazierPoints, Canvas canvas, Mode mode);

    /**
     * 画横线
     *
     * @param canvas
     * @param isAnim 是否开启动画
     */
    protected abstract void drawFlat(Canvas canvas, boolean isAnim);

    /**
     * 画横线，通过动画的方式
     */
    protected abstract void drawFlatByAnim();

    /**
     * 画向上的曲线
     *
     * @param canvas
     * @param isAnim 是否开启动画
     */
    protected abstract void drawUp(Canvas canvas, boolean isAnim);

    /**
     * 画向上的曲线，通过动画的方式
     */
    protected abstract void drawUpByAnim();

    /**
     * 画向下的曲线
     *
     * @param canvas
     * @param isAnim
     */
    protected abstract void drawDown(Canvas canvas, boolean isAnim);

    /**
     * 画向下的曲线，通过动画的方式
     */
    protected abstract void drawDownByAnim();

    public void handleStartAnim() {
        if (mIsRunging || mPer > 0) { // 动画首次启动
            return;
        }
        mIsAnim = true;
        invalidate();
    }

    protected void startAnim() {
        if (!mIsAnim) {
            return;
        }
        cancelAnim();
        mIsRunging = true;
        if (mAnimator == null) {
            mAnimator = new AnimatorValue();
            mAnimator.setCurveType(Animator.CurveType.LINEAR);
            mAnimator.setDuration(mAnimDuration);
        }
        mAnimator.setValueUpdateListener((animatorValue, v) -> {
            mPer = v;
            invalidate();
        });
        mAnimator.setStateChangedListener(new Animator.StateChangedListener() {
            @Override
            public void onStart(Animator animator) {

            }

            @Override
            public void onStop(Animator animator) {

            }

            @Override
            public void onCancel(Animator animator) {
                mIsRunging = false;
                mPer = 0f;
            }

            @Override
            public void onEnd(Animator animator) {
                getContext().getUITaskDispatcher().delayDispatch(() -> {
                    mIsRunging = false;
                    mPer = 0f;
                }, 120);
            }

            @Override
            public void onPause(Animator animator) {

            }

            @Override
            public void onResume(Animator animator) {

            }
        });
        mAnimator.start();

    }

    /**
     * 开启动画前先取消动画
     */
    public void cancelAnim() {
        if (mAnimator != null
                && (mAnimator.isRunning() || mIsRunging)) {
            mAnimator.cancel();
        }
    }

    protected enum Mode {
        Flat, // 平
        Up, // 升
        Down, // 降
        None // 空白，啥也不显示
    }

    /*public class Point {
        private float x;
        private float y;

        public Point(float x, float y) {
            this.x = x;
            this.y = y;
        }

        public float getX() {
            return x;
        }

        public void setX(float x) {
            this.x = x;
        }

        public float getY() {
            return y;
        }

        public void setY(float y) {
            this.y = y;
        }
    }*/
}
